using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Web.UI.Design;

namespace skmExpressionBuilders.Design
{
    public class ServerVariableExpressionEditor : ExpressionEditor
    {
        public override object EvaluateExpression(string expression, object parseTimeData, Type propertyType, IServiceProvider serviceProvider)
        {
            return string.Concat("[ServerVariable:", expression, "]");
        }

        public override ExpressionEditorSheet GetExpressionEditorSheet(string expression, IServiceProvider serviceProvider)
        {
            return new ServerVariableExpressionEditorSheet(expression, this, serviceProvider);
        }

        private class ServerVariableExpressionEditorSheet : ExpressionEditorSheet
        {
            private string _serverVariableName;
            private ServerVariableExpressionEditor _owner;

            public ServerVariableExpressionEditorSheet(string expression, ServerVariableExpressionEditor owner, IServiceProvider serviceProvider)
                : base(serviceProvider)
            {
                _serverVariableName = expression;
                _owner = owner;
            }

            public override string GetExpression()
            {
                return this._serverVariableName;
            }

            [DefaultValue(""), TypeConverter(typeof(ServerVariableTypeConverter))]
            public string ServerVariableName
            {
                get
                {
                    return _serverVariableName;
                }
                set
                {
                    _serverVariableName = value;
                }
            }

            public override bool IsValid
            {
                get
                {
                    return string.IsNullOrEmpty(this.ServerVariableName) == false;
                }
            }

            private class ServerVariableTypeConverter : TypeConverter
            {
                private readonly string NoServerVariableSetting = "(None)";

                public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
                {
                    if (context != null)
                    {
                        List<string> serverVariableNames = new List<string>();
                        serverVariableNames.Add("ALL_HTTP");
                        serverVariableNames.Add("ALL_RAW");
                        serverVariableNames.Add("APPL_MD_PATH");
                        serverVariableNames.Add("APPL_PHYSICAL_PATH");
                        serverVariableNames.Add("AUTH_TYPE");
                        serverVariableNames.Add("AUTH_USER");
                        serverVariableNames.Add("AUTH_PASSWORD");
                        serverVariableNames.Add("LOGON_USER");
                        serverVariableNames.Add("REMOTE_USER");
                        serverVariableNames.Add("CERT_COOKIE");
                        serverVariableNames.Add("CERT_FLAGS");
                        serverVariableNames.Add("CERT_ISSUER");
                        serverVariableNames.Add("CERT_KEYSIZE");
                        serverVariableNames.Add("CERT_SECRETKEYSIZE");
                        serverVariableNames.Add("CERT_SERIALNUMBER");
                        serverVariableNames.Add("CERT_SERVER_ISSUER");
                        serverVariableNames.Add("CERT_SERVER_SUBJECT");
                        serverVariableNames.Add("CERT_SUBJECT");
                        serverVariableNames.Add("CONTENT_LENGTH");
                        serverVariableNames.Add("CONTENT_TYPE");
                        serverVariableNames.Add("GATEWAY_INTERFACE");
                        serverVariableNames.Add("HTTP_HOST");
                        serverVariableNames.Add("HTTP_REFERER");
                        serverVariableNames.Add("HTTP_USER_AGENT");
                        serverVariableNames.Add("HTTPS");
                        serverVariableNames.Add("HTTPS_KEYSIZE");
                        serverVariableNames.Add("HTTPS_SECRETKEYSIZE");
                        serverVariableNames.Add("HTTPS_SERVER_ISSUER");
                        serverVariableNames.Add("HTTPS_SERVER_SUBJECT");
                        serverVariableNames.Add("INSTANCE_ID");
                        serverVariableNames.Add("INSTANCE_META_PATH");
                        serverVariableNames.Add("LOCAL_ADDR");
                        serverVariableNames.Add("PATH_INFO");
                        serverVariableNames.Add("PATH_TRANSLATED");
                        serverVariableNames.Add("QUERY_STRING");
                        serverVariableNames.Add("REMOTE_ADDR");
                        serverVariableNames.Add("REMOTE_HOST");
                        serverVariableNames.Add("REMOTE_PORT");
                        serverVariableNames.Add("REQUEST_METHOD");
                        serverVariableNames.Add("SCRIPT_NAME");
                        serverVariableNames.Add("SERVER_NAME");
                        serverVariableNames.Add("SERVER_PORT");
                        serverVariableNames.Add("SERVER_PORT_SECURE");
                        serverVariableNames.Add("SERVER_PROTOCOL");
                        serverVariableNames.Add("SERVER_SOFTWARE");
                        serverVariableNames.Add("URL");

                        return new TypeConverter.StandardValuesCollection(serverVariableNames);
                    }
                    
                    return base.GetStandardValues(context);
                }

                public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
                {
                    return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
                }

                public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
                {
                    return destinationType == typeof(string) ||  base.CanConvertTo(context, destinationType);
                }

                public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
                {
                    if (!(value is string))
                        return base.ConvertFrom(context, culture, value);
                    if (string.Compare(value as string, NoServerVariableSetting, true) == 0)
                        return string.Empty;
                    else
                        return value;
                }

                public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
                {
 	                 if (!(value is string))
                        return base.ConvertTo(context, culture, value, destinationType);
                    if ((value as string).Length == 0)
                        return NoServerVariableSetting;
                    else
                        return value;
                }

                public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
                {
                    return false;
                }

                public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
                {
                    return true;
                }
            }
        }
    }
}
